package com.jprocms.module.cms.service.content;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.jprocms.module.cms.dal.dataobject.channel.ChannelDO;
import com.jprocms.module.cms.dal.dataobject.content.ContentCountDO;
import com.jprocms.module.cms.dal.dataobject.content.ContentDO;
import com.jprocms.module.cms.dal.dataobject.site.SiteDO;
import com.jprocms.module.cms.dal.mysql.channel.ChannelMapper;
import com.jprocms.module.cms.dal.mysql.content.ContentCountMapper;
import com.jprocms.module.cms.dal.mysql.content.ContentMapper;
import com.jprocms.module.cms.dal.redis.RedisKeyConstants;
import com.jprocms.module.cms.framework.cache.CacheService;
import com.jprocms.module.cms.service.site.SiteService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.concurrent.TimeUnit;

/**
 * @author jprocms
 */
@Slf4j
@Service
public class ContentCountServiceImpl extends ServiceImpl<ContentCountMapper, ContentCountDO> implements ContentCountService {

    @Resource
    private ContentMapper contentMapper;
    @Resource
    private ChannelMapper channelMapper;
    @Resource
    private CacheService cacheService;
    @Resource
    private SiteService siteService;

    public Integer view(Long id) {
        ContentDO contentDO = contentMapper.selectById(id);
        if (contentDO == null) {
            return 0;
        }
        //统计栏目和站点浏览量
        increChannelViews(contentDO.getChannel());
        Integer cacheViewCount = cacheService.getCacheMapValue(RedisKeyConstants.CONTENT_VIEW, id.toString());
        if (cacheViewCount == null) {
            cacheViewCount = contentDO.getCount().getViews();
            cacheService.setCacheMapValue(RedisKeyConstants.CONTENT_VIEW, id.toString(), cacheViewCount);
            cacheService.incrCacheMapValue(RedisKeyConstants.CONTENT_VIEW, id.toString(), 1L);
            cacheService.expire(RedisKeyConstants.CONTENT_VIEW, 30, TimeUnit.MINUTES);
        } else {
            cacheService.incrCacheMapValue(RedisKeyConstants.CONTENT_VIEW, id.toString(), 1L);
        }
        //定时刷新缓存数据入库 refreshContentViewsCacheToDbHandler
        return cacheViewCount;
    }

    @Override
    public Long viewChannel(Long id) {
        ChannelDO channelDO = channelMapper.selectById(id);
        if (channelDO == null) {
            return 0L;
        }
        //统计栏目和站点浏览量
        increChannelViews(channelDO);
        Long cacheViewCount = Long.parseLong(cacheService.getCacheMapValue(RedisKeyConstants.CHANNEL_VIEW, id.toString()).toString());
        return cacheViewCount;
    }

    @Override
    public void viewIndex(Long id) {
        SiteDO siteDO = siteService.getSite(id);
        // 增加所属站点浏览次数
        doUpdateCache(RedisKeyConstants.SITE_VIEW, id.toString(), siteDO.getViews());
        doUpdateCache(RedisKeyConstants.SITE_DAY_VIEW, id.toString(), siteDO.getTodayViews());
        doUpdateCache(RedisKeyConstants.SITE_YEAR_VIEW, id.toString(), siteDO.getYearViews());
    }

    private void increChannelViews(ChannelDO channel) {
        // 增加所属站点浏览次数
        doUpdateCache(RedisKeyConstants.SITE_VIEW, channel.getSiteId().toString(), channel.getSite().getViews());
        doUpdateCache(RedisKeyConstants.SITE_DAY_VIEW, channel.getSiteId().toString(), channel.getSite().getTodayViews());
        doUpdateCache(RedisKeyConstants.SITE_YEAR_VIEW, channel.getSiteId().toString(), channel.getSite().getYearViews());
        // 增加栏目及上级栏目浏览次数
        for (ChannelDO bean : channel.getNodeList()) {
            doUpdateCache(RedisKeyConstants.CHANNEL_VIEW, bean.getId().toString(), bean.getViews());
            doUpdateCache(RedisKeyConstants.CHANNEL_DAY_VIEW, bean.getId().toString(), bean.getTodayViews());
            doUpdateCache(RedisKeyConstants.CHANNEL_YEAR_VIEW, bean.getId().toString(), bean.getYearViews());
        }
        //定时刷新缓存数据入库 refreshContentViewsCacheToDbHandler
    }


    private void doUpdateCache(String key, String id, Object dbval) {
        Object cacheViewCount = cacheService.getCacheMapValue(key, id);
        if (cacheViewCount == null) {
            cacheService.setCacheMapValue(key, id, dbval);
            if (StringUtils.isNotBlank(key) && key.contains("day-")) {
                cacheService.expire(key, 24, TimeUnit.HOURS);
            } else if (StringUtils.isNotBlank(key) && key.contains("year-")) {
                cacheService.expire(key, 365, TimeUnit.DAYS);
            }
        }
        cacheService.incrCacheMapValue(key, id, 1L);
    }

}
